package cz.muni.fi.pa165.sme.web.panels;

import cz.muni.fi.pa165.sme.web.fo.BurnedCaloriesFO;
import cz.muni.fi.pa165.sme.web.fo.SportActivityFO;
import cz.muni.fi.pa165.sme.web.fo.SportActivityRecordFO;
import cz.muni.fi.pa165.sme.web.fo.UserFO;
import cz.muni.fi.pa165.sme.web.pages.LoginPage;
import cz.muni.fi.pa165.sme.web.pages.LogoutPage;
import cz.muni.fi.pa165.sme.web.pages.RegistrationPage;
import cz.muni.fi.pa165.sme.web.pages.TemplatePage;
import cz.muni.fi.pa165.sme.web.pages.burnedCalories.CaloriesAddPage;
import cz.muni.fi.pa165.sme.web.pages.burnedCalories.CaloriesListPage;
import cz.muni.fi.pa165.sme.web.pages.sportActivity.ActivityAddPage;
import cz.muni.fi.pa165.sme.web.pages.sportActivity.ActivityListPage;
import cz.muni.fi.pa165.sme.web.pages.sportActivityRecord.RecordAddPage;
import cz.muni.fi.pa165.sme.web.pages.sportActivityRecord.RecordListPage;
import cz.muni.fi.pa165.sme.web.pages.user.UserAddPage;
import cz.muni.fi.pa165.sme.web.pages.user.UserListPage;
import cz.muni.fi.pa165.sme.web.security.Authorizer;
import org.apache.wicket.authorization.Action;
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeAction;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.ResourceModel;

/**
 * Application's main menu panel
 *
 * @author jirankova
 */
public class MenuPanel extends Panel {

	public MenuPanel(String id) {
		super(id);

		add(createLink(LoginPage.class, "loginMenu", UserFO.class, null));
		add(createLink(RegistrationPage.class, "registrationPage", UserFO.class, null));
		add(createLink(LogoutPage.class, "logoutPage", UserFO.class, Roles.USER));

		//users
		add(createLink(UserListPage.class, "userManagement", UserFO.class, Roles.ADMIN).add(new Label("userManagement", new ResourceModel(
				"menu.user.management"))));
		add(createLink(UserListPage.class, "userList", UserFO.class, Roles.USER));
		add(createLink(UserAddPage.class, "userAdd", UserFO.class, Roles.ADMIN));

		//sport activities
		add(createLink(ActivityListPage.class, "activityManagement", SportActivityFO.class, Roles.USER).add(new Label("activityManagement", new ResourceModel(
				"menu.activity.management"))));
		add(createLink(ActivityListPage.class, "activityList", SportActivityFO.class, Roles.USER));
		add(createLink(ActivityAddPage.class, "activityAdd", SportActivityFO.class, Roles.ADMIN));

		//activity records
		add(createLink(RecordListPage.class, "recordManagement", SportActivityRecordFO.class, Roles.USER).add(new Label("recordManagement", new ResourceModel(
				"menu.record.management"))));
		add(createLink(RecordListPage.class, "recordList", SportActivityRecordFO.class, Roles.USER));
		add(createLink(RecordAddPage.class, "recordAdd", SportActivityRecordFO.class, Roles.USER));

		//burned calories
		add(createLink(CaloriesListPage.class, "caloriesManagement", BurnedCaloriesFO.class, Roles.USER).add(new Label("caloriesManagement", new ResourceModel(
				"menu.calories.management"))));
		add(createLink(CaloriesListPage.class, "caloriesList", BurnedCaloriesFO.class, Roles.USER));
		add(createLink(CaloriesAddPage.class, "caloriesAdd", BurnedCaloriesFO.class, Roles.ADMIN));
	}

	/**
	 * Creates link fore the provided response page with the provided id and model class
	 * @param responsePage class of the response page
	 * @param linkId link wicket id
	 * @param linkClass model class of the link
	 * @param <T> link parameter class
	 * @param <S> response page parameter class
	 * @return link
	 */
	private <T, S extends TemplatePage> Link<T> createLink(final Class<S> responsePage, final String linkId, final Class<T> linkClass, final String role) {
		return new Link<T>(linkId) {
			@Override
			protected void onInitialize() {
				super.onInitialize();
				if(role == null) {
					Authorizer.authorizeCommon(this);
				} else if(role.equals(Roles.USER)){
					Authorizer.authorizeUser(this);
				} else if(role.equals(Roles.ADMIN)) {
					Authorizer.authorizeAdmin(this);
				} else {
					throw new IllegalStateException("Role " + role + " is not defined,");
				}

			}

			@Override
			public void onClick() {
				setResponsePage(responsePage);
			}
		};
	}
}
